package com.photoeditor.demo.ui.widget.collage;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Xfermode;
import android.os.Handler;
import android.os.Looper;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;

import com.common.base.ComponentContext;
import com.common.base.app.BaseActivity;
import com.photoeditor.R;
import com.photoeditor.demo.model.bean.BitmapBean;
import com.photoeditor.demo.model.image.collage.templet.CollagePoints;
import com.photoeditor.demo.model.image.collage.templet.Point;
import com.photoeditor.demo.model.image.collage.templet.attr.IStatus;
import com.photoeditor.demo.model.image.tools.MatrixAnimation;
import com.photoeditor.demo.ui.widget.TextureVideoView;
import com.photoeditor.demo.util.MediaTypeUtil;

import java.io.IOException;

import pl.droidsonroids.gif.GifBitmap;

/**
 * 实际的拼图的VIew一个View放置一个Bitmap
 * 注意几点：
 * （1）增加边距时，其实Path是不会变化的，变化的是mScale，它会根据需要在绘制的时候缩小Path，以达到需要的效果
 * （2）增加圆角时会修改当前的Path
 * （3）mDefaultRect是不会变化的，是没有边距时候的Rect
 * （4）由于缩小后的View会于Path的边界紧贴，所以绘制mIsTouch的效果时需要另一个缩放值，能将Border完全显示的缩放值和偏移量
 * （5）由于Path的坐标是以CollageRelativeLayout 中间的比例区域的左上点为（0, 0）点的，所以在绘制Path的时候需要平移
 * （6）图片的实际实现方式是通过Xfermode的叠加
 * （7）自己是没有监听任何事件的，是通过父View的分发实现各种动作的
 */
public class CollagePathView extends View implements ICollagePathView, GifBitmap.OnGifRefreshListener {

    /**
     * 变形动画的持续时间（毫秒）
     */
    private static final long DURATION_MATRIX_ANIMATION = 150L;
    private boolean mIsAnimationRunning = false;

    //Matirx动画相关
    private MatrixAnimation mMatrixAnimation = null;
    private Transformation mTransformation = null;

    //相对于父View的  View没有圆角和边距时的Rect
    private RectF mDefaultRect;

    //也是相对于父View的 当前View的Rect
    private RectF mCurrentRect;

    //当前Path的缩放值
//    private float mScaleX = 1.0f;
//    private float mScaleY = 1.0f;
    private float mTranslateX = 0.0f;
    private float mTranslateY = 0.0f;

    //绘制border的缩放值
    private float mBorderScaleX = 1.0f;
    private float mBorderScaleY = 1.0f;
    private float mBorderTranslateX = 0.0f;
    private float mBorderTranslateY = 0.0f;


    //特别注意 Path和Region都是以父View的比例区域（非所有父View） 左上点为 0,0点的
    private CollagePoints mCollage;
    private IStatus mPreAttr;//预属性  用于镜像功能
    private Path mPath;
    private Region mRegion;
    private RectF mPathRect;

    private static final Xfermode sXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private Paint mDSTPaint;
    private Paint mBitmapPaint;
    private Paint mBorderPaint;

    private final static int BORDER_WIDTH = ComponentContext.getContext().getResources().getDimensionPixelSize(R.dimen.image_collage_border_width);

//    private MyGestureListener mGestureListener;
//    private CollageGestureRecognizer mGestureRecognizer;

    //这三个是针对绘制图片的
    private Matrix mSupportMatrix;//第一次进入
    private Matrix mRotationMatrix;//旋转
    private Matrix mOppMatrix;//拉伸
    private Matrix mTranslateMatrix;//初始化平移
    private Matrix mDrawMatrix;//真正绘制
    private Matrix mCacheMatrix;//缓存

    //初始化后的DisplayRect
    private RectF mDefaultDisplayRect;

    private RectF mDisplayRect;

    private Bitmap mSourceBitmap;

    private boolean mIsInit = false;

    private final static int MSG_REFRESH = 1;

    private boolean mIsTouch = false;

    private boolean mIsInChange = false;

    private BaseActivity mActivity;


    private BitmapBean mBitmapBean;
    private GifBitmap mGifBitmap;
    private GifBitmap mGifBitmapForRender;
    private TextureVideoView.MediaPlayerCallback mMediaPlayerCallback;
    private int mId;
    private int mStartOffset;
    private Bitmap mLastFrameGifBitmap;
    private int mLastFrameIndex;

    private boolean mFromMirror = false;


    Handler mHandler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == MSG_REFRESH) {
                invalidate();
            }
        }

        ;
    };

    public CollagePathView(Context context, RectF rectF, Path path, RectF currentRect, RectF outSideRect, CollagePoints collage, IStatus preAttr) {
        super(context);
        init();
        mDefaultRect = rectF;
        mPathRect = new RectF();
        mRegion = new Region();
        mPath = path;
        mPath.computeBounds(mPathRect, false);
        //取交集部分
        mRegion.setPath(mPath, new Region((int) mPathRect.left, (int) mPathRect.top, (int) mPathRect.right, (int) mPathRect.bottom));
        mCollage = collage;
        mPreAttr = preAttr;
        setCurrentRect(currentRect, outSideRect);
    }

    public CollagePathView(Context context, RectF rectF, Path path, CollagePoints collage, IStatus preAttr) {
        super(context);
        init();
        mDefaultRect = rectF;
        mPathRect = new RectF();
        mRegion = new Region();
        mPath = path;
        mPath.computeBounds(mPathRect, false);
        mRegion.setPath(mPath, new Region((int) mPathRect.left, (int) mPathRect.top, (int) mPathRect.right, (int) mPathRect.bottom));
        mCollage = collage;
        mPreAttr = preAttr;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    public void setFromMirror(boolean mFromMirror) {
        this.mFromMirror = mFromMirror;
    }

    public void init() {
        if (isHardwareAccelerated()) {
            setLayerType(LAYER_TYPE_HARDWARE, null);
        }
//        setOnTouchListener(this);
//        mGestureListener = new MyGestureListener();
//        mGestureRecognizer = new CollageGestureRecognizer(getContext(), mGestureListener);
        mActivity = (BaseActivity) getContext();
        mSupportMatrix = new Matrix();
        mRotationMatrix = new Matrix();
        mOppMatrix = new Matrix();
        mTranslateMatrix = new Matrix();
        mCacheMatrix = new Matrix();
        mDrawMatrix = new Matrix();
        mDisplayRect = new RectF();
        mCurrentRect = new RectF();
        mDefaultDisplayRect = new RectF();


        mDSTPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mDSTPaint.setXfermode(sXfermode);

        mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBitmapPaint.setStyle(Paint.Style.FILL);
        mBitmapPaint.setColor(Color.WHITE);

        mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setColor(getResources().getColor(R.color.accent_color));
        mBorderPaint.setStrokeWidth(BORDER_WIDTH);

        refreshUI();
    }

    /**
     * 设置源图片
     *
     * @param bitmap
     */
    public void setSourceBitmap(Bitmap bitmap) {
        mSourceBitmap = bitmap;
        if (mSourceBitmap != null && !mSourceBitmap.isRecycled()) {
            setIsInit(true);
            reset();
            resetSupportMatrix();
            applyPreAttr();
            setDrawMatrix(countDrawMatrix());
        } else {
            setIsInit(false);
            reset();
        }
    }

    //暂时不需要支持Gif显示
    public void setBitmapBean(BitmapBean bitmapBean) {
        mBitmapBean = bitmapBean;
        if (mGifBitmap != null) {
            mGifBitmap.setOnGifRefreshListener(null);
            mGifBitmap.stop();
        }
        mGifBitmap = null;
        mGifBitmapForRender = null;
        if (mBitmapBean == null || mBitmapBean.mType != MediaTypeUtil.TYPE_GIF || mFromMirror) {
            return;
        }
        try {
            mGifBitmap = new GifBitmap(mBitmapBean.mPath);
            mGifBitmap.setLoopCount(1);
            mGifBitmapForRender = new GifBitmap(mBitmapBean.mPath);
            mGifBitmapForRender.stop();
            mLastFrameGifBitmap = mGifBitmapForRender.seekToPositionAndGet(getGifDuration());
            Bitmap bitmap = Bitmap.createBitmap(mLastFrameGifBitmap.getWidth(), mLastFrameGifBitmap.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(mLastFrameGifBitmap, 0, 0, null);
            mLastFrameGifBitmap = bitmap;
            mLastFrameIndex = mGifBitmapForRender.getFrameIndex(getGifDuration());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setVideoPath(String string) {
    }

    @Override
    public void onDestory() {
        setSourceBitmap(null);
        setBitmapBean(null);
    }

    @Override
    public void onResume() {
        if (mBitmapBean.mType == MediaTypeUtil.TYPE_GIF) {
            startPlayGif();
        }
    }

    @Override
    public void onPause() {
        if (mBitmapBean.mType == MediaTypeUtil.TYPE_GIF) {
            stopPlayGif();
        }
    }

    /**
     * gif图片刷新
     *
     * @param bitmap
     */
    @Override
    public void onRefresh(Bitmap bitmap) {
        if (mBitmapBean == null || mBitmapBean.mType != MediaTypeUtil.TYPE_GIF) {
            return;
        }
        mSourceBitmap = bitmap;
        invalidate();
    }

    /**
     * 设置滤镜处理后的图片
     *
     * @param bitmap
     */
    public void setFilterBitmap(Bitmap bitmap) {
        mSourceBitmap = bitmap;
        if (mSourceBitmap != null && !mSourceBitmap.isRecycled()) {
            setIsInit(true);
            setDrawMatrix(countDrawMatrix());
        } else {
            setIsInit(false);
            reset();
        }
    }

    /**
     * 初始化SupportMatrix
     */
    private void resetSupportMatrix() {
        mSupportMatrix.reset();
        float bw = mSourceBitmap.getWidth();
        float bh = mSourceBitmap.getHeight();

        float viewW = mDefaultRect.width();
        float viewH = mDefaultRect.height();

        float w, h;
        float scale;
        float translateX, translateY;
        if (bw / bh >= viewW / viewH) {//比较宽  这时候应高顶着高  才不会显示底图
            h = viewH;
            w = bw * viewH / bh;
            scale = w / bw;
            translateX = (viewW - w) / 2;
            translateY = 0.0f;
        } else {
            w = viewW;
            h = bh * viewW / bw;
            scale = w / bw;
            translateX = 0.0f;
            translateY = (viewH - h) / 2;
        }
        mSupportMatrix.postScale(scale, scale, 0, 0);
        mSupportMatrix.postTranslate(translateX, translateY);
        mDefaultDisplayRect.set(0, 0, bw, bh);
        //把坐标位置放入矩阵
        mSupportMatrix.mapRect(mDefaultDisplayRect);
    }

    /**
     * 应用预属性
     */
    public void applyPreAttr() {
        if (mPreAttr != null) {
            int rotate = mPreAttr.getRotate();
            Point point = mPreAttr.getTranslate();
            boolean flipH = mPreAttr.flipHorizontal();
            boolean flipV = mPreAttr.flipVertical();
            if (rotate != 0) {
                preRotation(rotate);
            }
            if (point.x != 0.0f || point.y != 0.0f) {
                preTranslate(point.x, point.y);
            }
            if (flipH) {
                preFlip(true);
            }
            if (flipV) {
                preFlip(false);
            }
        }
    }

    /**
     * 计算应用初始属性后的点
     *
     * @param dx
     * @param dy
     * @return
     */
    public float[] getPreCountTranslate(float dx, float dy) {
        if (mPreAttr != null) {
            float result[] = new float[2];
            int rotate = mPreAttr.getRotate();
            boolean flipH = mPreAttr.flipHorizontal();
            boolean flipV = mPreAttr.flipVertical();
            if (rotate != 0) {
                if ((rotate % 360 + 360) % 360 == 180) {
                    dx = -dx;
                    dy = -dy;
                }
            }
            if (flipH) {
                dx = -dx;
                dy = dy;
            }
            if (flipV) {
                dx = dx;
                dy = -dy;
            }
            result[0] = dx;
            result[1] = dy;
            return result;
        }
        return new float[]{dx, dy};
    }

    public RectF getDefaultRect() {
        return mDefaultRect;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isInit()) {
            int count = canvas.saveLayer(0.0f, 0.0f, getWidth(), getHeight(),
                    null, Canvas.ALL_SAVE_FLAG);
            if (!mIsInChange) {
                //没选中是对图片滑动
                if (mMatrixAnimation != null && !mMatrixAnimation.hasEnded()) {
                    // 如果动画还没结束，则获取当前变换过程的矩阵
                    mMatrixAnimation.getTransformation(
                            AnimationUtils.currentAnimationTimeMillis(),
                            mTransformation);
                    Matrix currMatrix = mTransformation.getMatrix();

                    if (currMatrix.equals(getDrawMatrix())) {
                        // 如果矩阵没有变化，可能是时间值间隔太短或动画刚刚开始，这时手动重绘
                        invalidate();
                    } else {
                        // 设置当前的矩阵变换，设置后会重绘
                        setDrawMatrix(mTransformation.getMatrix());
                    }
                } else {
                    // 动画已经结束播放了，重新修改状态值
                    mIsAnimationRunning = false;
                }
                int count2 = canvas.save();
                canvas.drawBitmap(mSourceBitmap, getDrawMatrix(), mBitmapPaint);
                canvas.translate(mTranslateX, mTranslateY);
                canvas.drawPath(mPath, mDSTPaint);
                canvas.restoreToCount(count2);
            }
            //点击绘制显示边界
            if (mIsTouch) {
                int count3 = canvas.save();
                canvas.scale(mBorderScaleX, mBorderScaleY);
                canvas.translate(mBorderTranslateX, mBorderTranslateY);
                canvas.drawPath(mPath, mBorderPaint);
                canvas.restoreToCount(count3);
            }

            canvas.restoreToCount(count);
        }
    }

    /**
     * 设置是否选中
     *
     * @param istouch
     */
    public void setIsTouch(boolean istouch) {
        if (mIsTouch != istouch) {
            mIsTouch = istouch;
            refresh();
        }
    }

    /**
     * 是否是选中状态
     *
     * @return
     */
    public boolean isTouch() {
        return mIsTouch;
    }

    /**
     * 获取当前的Path
     *
     * @return
     */
    public Path getPath() {
        return mPath;
    }

    /**
     * 获取当前Path的区域
     *
     * @return
     */
    public Region getRegion() {
        return mRegion;
    }

    /**
     * 设置当前的Path
     *
     * @param path
     */
    public void setPath(Path path) {
        mPath.set(path);
        mPath.computeBounds(mPathRect, false);
        mRegion.setPath(mPath, new Region((int) mPathRect.left, (int) mPathRect.top, (int) mPathRect.right, (int) mPathRect.bottom));
    }

    @Override
    public void resetBound() {

    }

    /**
     * 设置当前View显示的RectF,选中边界
     *
     * @param currentRect
     * @param outSideRect
     */
    public void setCurrentRect(RectF currentRect, RectF outSideRect) {
        mCurrentRect.set(currentRect);
//        mTranslateX = outSideRect.left - mDefaultRect.left;
//        mTranslateY = outSideRect.top - mDefaultRect.top;
        mTranslateX = outSideRect.left - mCurrentRect.left;
        mTranslateY = outSideRect.top - mCurrentRect.top;
//        mScaleX = mCurrentRect.width() / mDefaultRect.width();
//        mScaleY = mCurrentRect.height() / mDefaultRect.height();
        mBorderScaleX = (mCurrentRect.width() - BORDER_WIDTH) / mCurrentRect.width();
        mBorderScaleY = (mCurrentRect.height() - BORDER_WIDTH) / mCurrentRect.height();
        mBorderTranslateX = mTranslateX + BORDER_WIDTH / 2;
        mBorderTranslateY = mTranslateY + BORDER_WIDTH / 2;

        mTranslateMatrix.reset();
        mTranslateMatrix.postTranslate(mDefaultRect.left - mCurrentRect.left, mDefaultRect.top - mCurrentRect.top);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureRect(rectF, null);
        setDrawMatrix(countDrawMatrix(), false);
    }

    /**
     * 获取当前View显示的RectF
     *
     * @return
     */
    public RectF getCurrentRect() {
        return mCurrentRect;
    }

    /**
     * 获取当前的Collage
     *
     * @return
     */
    public CollagePoints getCollage() {
        return mCollage;
    }

    /**
     * 设置新的数据并刷新显示
     * 图片不会更改
     *
     * @param rectF
     * @param path
     * @param currentRect
     * @param outSideRect
     * @param collage
     */
    public void setData(RectF rectF, Path path, RectF currentRect, RectF outSideRect, CollagePoints collage, IStatus preAttr) {
        reset();
        mDefaultRect = rectF;
        mPath = path;
        mPath.computeBounds(mPathRect, false);
        mRegion.setPath(mPath, new Region((int) mPathRect.left, (int) mPathRect.top, (int) mPathRect.right, (int) mPathRect.bottom));
        mCollage = collage;
        mPreAttr = preAttr;
        if (mSourceBitmap != null && !mSourceBitmap.isRecycled()) {
            setIsInit(true);
            resetSupportMatrix();
            setCurrentRect(currentRect, outSideRect);
            applyPreAttr();
            setDrawMatrix(countDrawMatrix());
        } else {
            setCurrentRect(currentRect, outSideRect);
            setIsInit(false);
        }
    }

    @Override
    public void updateData(RectF rectF, Path path, RectF currentRect, RectF outSideRect, CollagePoints collage, IStatus preAttr) {
        resetBaseMatrix();
        mDefaultRect = rectF;
        mPath = path;
        mPath.computeBounds(mPathRect, false);
        mRegion.setPath(mPath, new Region((int) mPathRect.left, (int) mPathRect.top, (int) mPathRect.right, (int) mPathRect.bottom));
        mCollage = collage;
        mPreAttr = preAttr;
        if (mSourceBitmap != null && !mSourceBitmap.isRecycled()) {
            setIsInit(true);
            resetSupportMatrix();
            setCurrentRect(currentRect, outSideRect);
            applyPreAttr();
            setDrawMatrix(countDrawMatrix());
        } else {
            setCurrentRect(currentRect, outSideRect);
            setIsInit(false);
        }
    }

    /**
     * 重置所有的矩阵
     */
    public void reset() {
        mSupportMatrix.reset();
        mRotationMatrix.reset();
        mCacheMatrix.reset();
        mOppMatrix.reset();
        mDrawMatrix.reset();
        mTranslateMatrix.reset();
    }

    private void resetBaseMatrix() {
        mSupportMatrix.reset();
        mCacheMatrix.reset();
        mDrawMatrix.reset();
    }

    /**
     * 使用动画模式设置矩阵对象，并实现平滑变换。设置后动画随即开始
     *
     * @param matrix 需要变换的目标矩阵对象
     */
    public void setAnimationImageMatrix(Matrix matrix) {
        if (!mIsInChange) {
            mIsAnimationRunning = true;

            if (mTransformation == null) {
                mTransformation = new Transformation();
            }

            if (mMatrixAnimation == null) {
                mMatrixAnimation = new MatrixAnimation(getDrawMatrix(), matrix);
                mMatrixAnimation.setDuration(DURATION_MATRIX_ANIMATION);
            }

            mMatrixAnimation.setFromMatrix(getDrawMatrix());
            mMatrixAnimation.setToMatrix(matrix);
            mMatrixAnimation.start();
            refresh();
        } else {
            setDrawMatrix(matrix);
        }
    }

    /**
     * 用于设置是否初始化
     *
     * @param isInit
     */
    public void setIsInit(boolean isInit) {
        mIsInit = isInit;
    }

    /**
     * 是否初始化
     *
     * @return
     */
    public boolean isInit() {
        return mIsInit;
    }

    /**
     * 获取当前的源图片
     *
     * @return
     */
    public Bitmap getSourceBitmap() {
        return getSourceBitmap(0);
    }

    /**
     * 获取当前的源图片
     *
     * @return
     */
    public Bitmap getSourceBitmap(long timestamp) {
        if (mGifBitmapForRender != null) {
            long time;
            if (timestamp <= mStartOffset) {
                time = 0;
            } else if (timestamp >= mStartOffset + getGifDuration()) {
                time = getGifDuration();
            } else {
                time = timestamp - mStartOffset;
            }
            Bitmap bitmap;
            int frameIndex = mGifBitmapForRender.getFrameIndex((int) time);
            if (frameIndex == mLastFrameIndex) {
                bitmap = mLastFrameGifBitmap;
            } else {
                bitmap = mGifBitmapForRender.seekToFrameAndGet(frameIndex);
            }

            return bitmap;
        }
        return mSourceBitmap;
    }

    public BitmapBean getBitmapBean() {
        return mBitmapBean;
    }

    public boolean isGif() {
        return mBitmapBean != null && mGifBitmap != null;
    }

    public int getGifDuration() {
        return (mBitmapBean != null && mBitmapBean.mType == MediaTypeUtil.TYPE_GIF) ? (int) mBitmapBean.mDuration : 0;
    }

    public void stopPlayGif() {
        if (mGifBitmap != null) {
            removeCallbacks(mPlayGifFinishRunnable);
            mGifBitmap.setOnGifRefreshListener(null);
            mGifBitmap.stop();
        }
    }

    public void seek2Begin() {
        if (mGifBitmap != null) {
            mGifBitmap.seekTo(0);
        }
    }

    public void startPlayGif() {
        if (mGifBitmap != null) {
            mGifBitmap.setOnGifRefreshListener(this);
            mGifBitmap.seekTo(0);
            mGifBitmap.start();
            removeCallbacks(mPlayGifFinishRunnable);
            postDelayed(mPlayGifFinishRunnable, getGifDuration());
        }
    }

    public void setMediaPlayerCallback(TextureVideoView.MediaPlayerCallback mediaPlayerCallback, int id) {
        mMediaPlayerCallback = mediaPlayerCallback;
        mId = id;
    }

    private Runnable mPlayGifFinishRunnable = new Runnable() {
        @Override
        public void run() {
            stopPlayGif();
            seek2Begin();
            invalidate();
            if (mMediaPlayerCallback != null) {
                mMediaPlayerCallback.onCompletion(null, mId);
            }
        }
    };

    /**
     * 计算当前的Draw Matrix
     *
     * @return
     */
    public Matrix countDrawMatrix() {
        mCacheMatrix.reset();
        mCacheMatrix.set(mSupportMatrix);
        mCacheMatrix.postConcat(mRotationMatrix);
        mCacheMatrix.postConcat(mOppMatrix);
        mCacheMatrix.postConcat(mTranslateMatrix);
        return mCacheMatrix;
    }

    /**
     * 获取Draw matrix
     *
     * @return
     */
    public Matrix getDrawMatrix() {
        return new Matrix(mDrawMatrix);
    }

    /**
     * 设置Draw Matrix 并刷新
     *
     * @param matrix
     */
    public void setDrawMatrix(Matrix matrix) {
        mDrawMatrix.set(matrix);
        refresh();
    }

    /**
     * 设置Draw Matrix 并刷新
     *
     * @param matrix
     * @param needRefresh 是否需要刷新
     */
    public void setDrawMatrix(Matrix matrix, boolean needRefresh) {
        mDrawMatrix.set(matrix);
        if (needRefresh) {
            refresh();
        }
    }

    /**
     * 旋转
     *
     * @param degree
     */
    public void rotation(int degree) {
        mRotationMatrix.postRotate(degree, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
        setDrawMatrix(countDrawMatrix());
    }

    /**
     * 翻转
     *
     * @param horizontal
     */
    public void flip(boolean horizontal) {
        if (horizontal) {
            mRotationMatrix.postScale(-1, 1, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        } else {
            mRotationMatrix.postScale(1, -1, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        }
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
        setDrawMatrix(countDrawMatrix());
    }

    //保证不会出现背景
    public void ensureNotInside(RectF rectF) {
//        RectF mViewCacheRect = new RectF();
//        float width = mCurrentRect.width();
//        float height = mCurrentRect.height();
//        float dx = 0, dy = 0;
//
//        float scale = 1.0f;
//        if(rectF.height() > height){//对上下边的处理
//            if(rectF.top > 0f){
//                dy = -rectF.top;
//            } else if(rectF.bottom < height){
//                dy = height - rectF.bottom;
//            }
//        } else{//高度比View高度小  需要居中
//            mViewCacheRect.set(0, 0, width, height);
//            dy = (mViewCacheRect.height() - rectF.height()) / 2 + mViewCacheRect.top - rectF.top;
//            scale = height / rectF.height();
//        }
//        if(rectF.width() > width){//对左右边的处理
//            if(rectF.left > 0f){
//                dx = -rectF.left;
//            } else if(rectF.right < width){
//                dx = width - rectF.right;
//            }
//        } else{//宽度比View高度小  需要居中
//            mViewCacheRect.set(0, 0, width, height);
//            dx = (mViewCacheRect.width() - rectF.width()) / 2 + mViewCacheRect.left - rectF.left;
//            if(rectF.width() * scale < width){
//                scale = width / rectF.width();
//            }
//        }
//        mOppMatrix.postTranslate(dx, dy);
//        if(scale != 1.0f) {
//            mOppMatrix.postScale(scale, scale, mViewCacheRect.centerX(), mViewCacheRect.centerY());
//        }
    }


    //刷新界面显示
    public void refresh() {
        if (!mHandler.hasMessages(MSG_REFRESH)) {
            mHandler.sendEmptyMessage(MSG_REFRESH);
        }
    }


    /**
     * 获取当前Bitmap 的绘制Rect
     *
     * @param matrix
     * @return
     */
    public RectF getDisplayRect(Matrix matrix) {
        if (null != mSourceBitmap) {
            mDisplayRect.set(0, 0, mSourceBitmap.getWidth(),
                    mSourceBitmap.getHeight());
            matrix.mapRect(mDisplayRect);
            return mDisplayRect;
        } else {
            mDisplayRect.set(0, 0, 0, 0);
        }
        return mDisplayRect;
    }

    public float getTranslateX() {
        return mTranslateX;
    }

    public float getTranslateY() {
        return mTranslateY;
    }

    /**
     * 计算合适的偏移量  当前显示Rect大于View的宽高时  保证不出边界
     * 当前显示Rect小于View的宽高时  保证居中
     *
     * @param rectF
     * @param matrix 传入Matrix的话就会对Matrix执行
     */
    private void ensureRect(RectF rectF, Matrix matrix) {
//        RectF mViewCacheRect = new RectF();
//        float width = mCurrentRect.width();
//        float height = mCurrentRect.height();
//        float dx = 0, dy = 0;
//        if(rectF.height() > height){//对上下边的处理
//            if(rectF.top > 0f){
//                dy = -rectF.top;
//            } else if(rectF.bottom < height){
//                dy = height - rectF.bottom;
//            }
//        } else{//高度比View高度小  需要居中
//            mViewCacheRect.set(0, 0, width, height);
//            dy = (mViewCacheRect.height() - rectF.height()) / 2 + mViewCacheRect.top - rectF.top;
//        }
//        if(rectF.width() > width){//对左右边的处理
//            if(rectF.left > 0f){
//                dx = -rectF.left;
//            } else if(rectF.right < width){
//                dx = width - rectF.right;
//            }
//        } else{//宽度比View高度小  需要居中
//            mViewCacheRect.set(0, 0, width, height);
//            dx = (mViewCacheRect.width() - rectF.width()) / 2 + mViewCacheRect.left - rectF.left;
//        }
//        if(matrix == null) {
//            mOppMatrix.postTranslate(dx, dy);
//        } else {
//            matrix.postTranslate(dx, dy);
//        }
    }

    /**
     * 返回true代表移动了
     *
     * @param data
     * @return
     */
    public boolean isNeedEnsureRect(float data[]) {
        RectF rectF = getDisplayRect(getDrawMatrix());
        RectF mViewCacheRect = new RectF();
        float dx = 0, dy = 0;
        if (rectF.height() > getHeight()) {//对上下边的处理
            if (rectF.top > 0f) {
                dy = -rectF.top;
            } else if (rectF.bottom < getHeight()) {
                dy = getHeight() - rectF.bottom;
            }
        } else {//高度比View高度小  需要居中
            mViewCacheRect.set(0, 0, getWidth(), getHeight());
            dy = (mViewCacheRect.height() - rectF.height()) / 2 + mViewCacheRect.top - rectF.top;
        }
        if (rectF.width() > getWidth()) {//对左右边的处理
            if (rectF.left > 0f) {
                dx = -rectF.left;
            } else if (rectF.right < getWidth()) {
                dx = getWidth() - rectF.right;
            }
        } else {//宽度比View高度小  需要居中
            mViewCacheRect.set(0, 0, getWidth(), getHeight());
            dx = (mViewCacheRect.width() - rectF.width()) / 2 + mViewCacheRect.left - rectF.left;
        }

        data[0] = -dx;
        data[1] = -dy;
        if (Math.abs(dx) > getWidth() / 5 || Math.abs(dy) > getHeight() / 5) {
            return true;
        } else {
            return false;
        }
    }


    private boolean mIsScale = false;
    private boolean mIsRotation = false;

    @Override
    public boolean onSingleTapUp(float x, float y) {
        return true;
    }

    @Override
    public boolean onSingleTapComfirm(float x, float y) {
        if (!mIsInit) return false;
        return true;
    }

    @Override
    public boolean onDoubleTap(float x, float y) {
        return false;
    }

    @Override
    public boolean onScroll(float x, float y, float dx, float dy, float totalX, float totalY) {
        if (!mIsInit) return false;
        if (!mIsScale) {
            float translateX = -dx;
            float translateY = -dy;

//            这段代码是不让他移出边界
//            RectF displayRect = getDisplayRect(countDrawMatrix());
//            /**
//             * 一些特殊情况的处理
//             */
//            if(displayRect.width() <= (float)(getWidth())){
//                translateX = 0f;
//            } else{
//            }
//
//            if(displayRect.height() <= getHeight()){
//                translateY = 0f;
//            }
//
//            if(displayRect.height() > getHeight()){
//                if(displayRect.top + translateY > 0f){
//                    translateY = -displayRect.top;
//                } else if(displayRect.bottom + translateY < getHeight()){
//                    translateY = getHeight() - displayRect.bottom;
//                }
//            }
//            if(displayRect.width() > getWidth()){
//                if(displayRect.left + translateX > 0f){
//                    translateX = -displayRect.left;
//                } else if(displayRect.right + translateX < getWidth()){
//                    translateX = getWidth() - displayRect.right;
//                }
//            }
//            if(translateX != 0 || translateY != 0) {
//                mOppMatrix.postTranslate(translateX, translateY);
//                setDrawMatrix(countDrawMatrix());
//            }

            mOppMatrix.postTranslate(translateX, translateY);
            setDrawMatrix(countDrawMatrix());
        }
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (!mIsInit) return false;
        return true;
    }

    @Override
    public boolean onScaleBegin(float focusX, float focusY) {
        if (!mIsInit) return false;
        mIsScale = true;
        return true;
    }

    @Override
    public boolean onScale(float focusX, float focusY, float scale) {
        if (!mIsInit) return false;
        if (Float.isNaN(scale) || Float.isInfinite(scale)) return false;

        Matrix drawMatrix = countDrawMatrix();
        RectF rect = getDisplayRect(drawMatrix);
        if (rect.width() * scale < getWidth() || rect.height() * scale < getHeight()) {
            drawMatrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);
            rect = getDisplayRect(drawMatrix);
            mOppMatrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);
            ensureRect(rect, null);
        } else {
            drawMatrix.postScale(scale, scale, focusX, focusY);
            rect = getDisplayRect(drawMatrix);
            mOppMatrix.postScale(scale, scale, focusX, focusY);
            ensureRect(rect, null);
        }
        setDrawMatrix(countDrawMatrix());
        return true;
    }

    @Override
    public void onScaleEnd() {
        if (!mIsInit) return;
        mIsScale = false;
    }

    @Override
    public boolean onRotaionBegin() {
        if (!mIsInit) return false;
        mIsRotation = true;
        return true;
    }

    @Override
    public boolean onRotaion(float delta) {
        rotation((int) (-delta));
        return true;
    }

    @Override
    public void onRotaionEnd() {
        if (!mIsInit) return;
        mIsRotation = false;
    }

    @Override
    public void onDown(float x, float y) {
        if (!mIsInit) return;
        mIsScale = false;
    }

    @Override
    public void onUp(float x, float y) {
        if (!mIsInit) return;
        mIsScale = false;
//        RectF displayRect = getDisplayRect(countDrawMatrix());
//        //判断需不需要复原
//        if(displayRect.width() < getWidth() || displayRect.height() < getHeight()
//                || displayRect.left > 0f || displayRect.right < getWidth()
//                || displayRect.top > 0f || displayRect.bottom < getHeight()){
//            if(displayRect.width() < getWidth() || displayRect.height() < getHeight()) {//宽或者高比需要显示的小 需要复原
//                mOppMatrix.reset();
//                mTranslateMatrix.reset();
//                setAnimationImageMatrix(countDrawMatrix());
//            } else{//不需要复原只需要平移到合适位置
//                if(displayRect.left > 0){//左边
//                    mOppMatrix.postTranslate(-displayRect.left, 0);
//                }
//
//                if(displayRect.top > 0){
//                    mOppMatrix.postTranslate(0, -displayRect.top);
//                }
//
//                if(displayRect.right < getWidth()){
//                    mOppMatrix.postTranslate(getWidth() - displayRect.right, 0);
//                }
//
//                if (displayRect.bottom < getHeight()) {
//                    mOppMatrix.postTranslate(0, getHeight() - displayRect.bottom);
//                }
//                setAnimationImageMatrix(countDrawMatrix());
//            }
//        }
    }

    @Override
    public void onLongPress(float x, float y) {

    }

    public void setIsInChange(boolean isInChange) {
        if (mIsInChange != isInChange) {
            mIsInChange = isInChange;
            refresh();
        }
    }

    public boolean isInChange() {
        return mIsInChange;
    }

    /**
     * 获取当前的显示
     *
     * @param alpha 在0-255之间  255微不透明，0为全透明
     * @return
     */
    public Bitmap getCurrentBitmap(int alpha) {
        int w = getWidth();
        int h = getHeight();
        w = Math.max(w, 2);
        h = Math.max(h, 2);
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        if (isInit()) {//这中间的代码就是用onDraw修改
            int count = canvas.saveLayerAlpha(0.0f, 0.0f, getWidth(), getHeight(), alpha, Canvas.ALL_SAVE_FLAG);
            if (mMatrixAnimation != null && !mMatrixAnimation.hasEnded()) {
                // 如果动画还没结束，则获取当前变换过程的矩阵
                mMatrixAnimation.getTransformation(
                        AnimationUtils.currentAnimationTimeMillis(),
                        mTransformation);
                Matrix currMatrix = mTransformation.getMatrix();

                if (currMatrix.equals(getDrawMatrix())) {
                    // 如果矩阵没有变化，可能是时间值间隔太短或动画刚刚开始，这时手动重绘
                    invalidate();
                } else {
                    // 设置当前的矩阵变换，设置后会重绘
                    setDrawMatrix(mTransformation.getMatrix());
                }
            } else {
                // 动画已经结束播放了，重新修改状态值
                mIsAnimationRunning = false;
            }

            Matrix matrix = getDrawMatrix();
            RectF rectF = getDisplayRect(matrix);
            ensureRect(rectF, matrix);
            canvas.drawBitmap(getSourceBitmap(), matrix, mBitmapPaint);

            canvas.restoreToCount(count);
        }
        return bitmap;
    }

    public void refreshUI() {
        mBorderPaint.setColor(getResources().getColor(R.color.collage_main_selected_color));
        if (mIsTouch) {
            refresh();
        }
    }

    /**
     * 平移
     *
     * @param dx
     * @param dy
     */
    public void preTranslate(float dx, float dy) {
        mOppMatrix.postTranslate(dx, dy);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
    }

    /**
     * 旋转
     *
     * @param degree
     */
    public void preRotation(int degree) {
        mRotationMatrix.postRotate(degree, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
    }

    /**
     * 翻转
     *
     * @param horizontal
     */
    public void preFlip(boolean horizontal) {
        if (horizontal) {
            mRotationMatrix.postScale(-1, 1, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        } else {
            mRotationMatrix.postScale(1, -1, mDefaultRect.width() / 2, mDefaultRect.height() / 2);
        }
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
    }

    /**
     * 平移 这个方法用于当前选中的View进行平移  需要跟随手指  然后反向计算其他的应该进行的初始值
     *
     * @param dx
     * @param dy
     */
    public float[] translateWidthoutPreAttr(float dx, float dy) {
        float dst[] = getPreCountTranslate(1, 1);
        mOppMatrix.postTranslate(dx, dy);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
        setDrawMatrix(countDrawMatrix());
        return new float[]{dst[0] * dx, dst[1] * dy};
    }

    /**
     * 平移
     *
     * @param dx
     * @param dy
     */
    public void translateWidthPreAttr(float dx, float dy) {
        float dst[] = getPreCountTranslate(dx, dy);
        mOppMatrix.postTranslate(dst[0], dst[1]);
        Matrix matrix = countDrawMatrix();
        RectF rectF = getDisplayRect(matrix);
        ensureNotInside(rectF);
        setDrawMatrix(countDrawMatrix());
    }

    public void setStartOffset(int startOffset) {
        mStartOffset = startOffset;
    }
}
